home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / New System Software Extensions / QuickDraw™ GX v1.0ß2 / Sample Code / Printing Samples / Printer Drivers… / LaserWriterIISC / OldAPIMessageIntf.c < prev    next >
Encoding:
Text File  |  1993-09-13  |  17.7 KB  |  608 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     OldAPIMessageIntf.c
  4.  
  5. DESCRIPTION
  6.     This module contains the routines which implement the old API messages
  7.     that the LaserWriter SC driver overrides.  Much of the logic in this
  8.     module was gleaned from the original LaserWriter IISC driver, and so
  9.     some of the calulations may seem a little strange.  In order to maintain
  10.     compatibility with the old driver's logic, we must preserve much of the
  11.     old logic.
  12.     
  13.     9/13/93 - dmh - Updated for the b2 seed.
  14.         
  15. COPYRIGHT
  16.      Copyright Apple Computer, Inc. 1989-1992
  17.      All rights reserved. 
  18.         
  19. INTERFACE ROUTINES:
  20.  
  21.     SD_PrValidate
  22.     SD_ConvertPrintRecordTo
  23.     SD_ConvertPrintRecordFrom
  24.  
  25. -------------------------------------------------------------------------------- */
  26.  
  27. // Include the standard Mac header files 
  28. #include "MacIncludes.h"
  29.  
  30. // Include the new QuickDraw GX graphics header files 
  31. #include <graphics routines.h>
  32. #include <graphics libraries.h>
  33. #include <math routines.h>
  34.  
  35. // Include the required Printing Manager header files 
  36. #include <PrintingManager.h>
  37. #include <PrintingMessages.h>
  38. #include <PrintingDrivers.h>
  39. #include <Collections.h>
  40. #include <Messages.h>
  41. #include <PrintingResTypes.h>
  42. #include <PrintingErrors.h>
  43.  
  44. // Include the internal driver constants and types used by this module 
  45. #include "Resources.h"
  46. #include "OldAPIMessageIntf.h"
  47.  
  48.  
  49. /***************************************************************************************
  50. *                                         INTERNAL ROUTINES                                                    *
  51. ***************************************************************************************/
  52.  
  53.  
  54. /****************************************************************************************
  55.  
  56.                             EmulatePages
  57.                             
  58.     function:
  59.                 This function takes a paper rectangle, and computes the rPage
  60.                 rectangle for it.  It uses the old LaserWriter IISC driver's page size 
  61.                 calculation "algorithm" (if it can be called such).
  62.                 
  63.     parameters:                
  64.                 hPrint        target print record whose rPage rect is updated
  65.  
  66.     returns:
  67.                 none
  68.     
  69. ****************************************************************************************/
  70. void EmulatePages(THPrint    hPrint)
  71. {
  72.     TPrInfo    *pPrInfo;
  73.     TPrStl    *pPrStl;
  74.     short        dvPaper;         // the "calculated" paper sizes
  75.     short        dhPaper;            
  76.     short        dvPage;             // the "calculated" page sizes
  77.     short        dhPage;            
  78.     short        iOneFourth;        // fudge factors which don't quite equal their names
  79.     short        iTwoFifths;        
  80.     short        iVMaxInch;        // memory limitation on the page sizes.
  81.     short        iHMaxBytes;
  82.     short        scanBits;        // the eventual # of bits across a line on the page (truncated)
  83.     short        scanLines;        // the eventual # of lines on the page (truncated)
  84.     short        iTemp;            // temporary swapping variable for landscape
  85.     short        hOff;                // used to calculated the offset paper rectangle
  86.     short        vOff;
  87.  
  88.     
  89.     pPrInfo    =    &((*hPrint)->prInfo);        
  90.     pPrStl    =    &((*hPrint)->prStl);        
  91.     
  92.  
  93.     dvPaper     =     (pPrStl->iPageV * pPrInfo->iVRes) / kMysticPaperFract;
  94.     dhPaper     =     (pPrStl->iPageH * pPrInfo->iHRes) / kMysticPaperFract;
  95.     
  96.     
  97.     // Weird fudge factors from Dave Casseres. No, I don't understand them.  No,
  98.     //    he apparently doesn't either, anymore. 
  99.         
  100.     iOneFourth    =    (pPrInfo->iHRes + 2) / 4;                // this isn't even 1/4th.
  101.     iTwoFifths    =    ((pPrInfo->iHRes << 2) + 5) / 10;    // nor is this 2/5ths!
  102.     
  103.     
  104.     // Boundary condition for large page sizes (legal > 1400 which is 11.666666667").
  105.     //    If the paper is smaller than that, then we just do the regular calculation.
  106.     //    Otherwise, we restrict the size to 12.5" on the IISC (25/2). Further, we
  107.     //    restrict the horizontal dimensions to 6.72 inches (memory limitation on 1 Mb printers
  108.         
  109.     if (pPrStl->iPageV <= 1400)
  110.     {
  111.         iVMaxInch     =     pPrStl->iPageV;
  112.         iHMaxBytes    =    kLetterRowBytes;
  113.     }
  114.     else
  115.     {
  116.         iVMaxInch     =     (25 * kMysticPaperFract) / 2;
  117.         iHMaxBytes    =    kLegalRowBytes;
  118.     }
  119.  
  120.  
  121.     // Force the horizontal dimension to fit within the laser's restrictions:
  122.     //    iHMaxBytes was just set. For letter, it's 8" (300 rowBytes). Multiply by the
  123.     //    horizontal resolution (say 72), and divide by high-resolution (300 dpi).
  124.     //    Multiply by 8 (<< 3), since we want coordinates, and the iHMaxBytes is
  125.     //    a byte count.  Always do divisions last, in order to keep precision. 
  126.     //    dhPaper is the paper size horizontally in rendering units (72 or 300). 
  127.     //    It really ought to be in one unit or the other, but in emulation mode,
  128.     //    it's in whatever the app selected.  We force the page size to fit within
  129.     //    the laser's restricted area by forcing about a 1/4" border. We do the same
  130.     //    vertically, with approximately a 2/5" border total. We truncate the results
  131.     //    (why to 16ths and to 2nds? I don't know). 
  132.     
  133.     scanBits = ((iHMaxBytes * pPrInfo->iHRes) << 3) / kHorizHighRes;
  134.     if (scanBits > (dhPaper - iOneFourth))
  135.         scanBits = dhPaper - iOneFourth;
  136.     scanBits = (scanBits >> 4) << 4;        // number of bits on a single line
  137.  
  138.  
  139.     scanLines = (iVMaxInch * pPrInfo->iVRes) / iPrPgFract;
  140.     if (scanLines > (dvPaper - iTwoFifths))
  141.         scanLines = dvPaper - iTwoFifths;
  142.     scanLines = (scanLines >> 1) << 1;        // number of lines on the page
  143.     
  144.  
  145.     // set the page size based on the orientation. Portrait uses the default
  146.     //    definitions: bits for horizontal and lines for vertical. 
  147.         
  148.     if ( TestBit((*hPrint)->prStl.wDev, kPortraitBit) )
  149.     {
  150.         dhPage = scanBits;
  151.         dvPage = scanLines;
  152.     }
  153.     else    // landscape
  154.     {
  155.         dhPage     = scanLines;
  156.         dvPage     = scanBits;
  157.         
  158.         // Reverse the meanings of paper in landscape as well. 
  159.         iTemp     = dhPaper;
  160.         dhPaper     = dvPaper;
  161.         dvPaper     = iTemp;
  162.     }
  163.  
  164.     SetRect( &(pPrInfo->rPage), 0, 0, dhPage, dvPage );
  165.  
  166.     // Create the paper size and store it in the print record 
  167.     
  168.     hOff = (dhPage - dhPaper) / 2;
  169.     vOff = (dvPage - dvPaper) / 2;
  170.     SetRect( & ((*hPrint)->rPaper) , hOff, vOff, dhPaper+hOff, dvPaper+vOff );
  171.  
  172.     // Preserve the rPaper rectangle in the printX array starting at word 5.  This is done
  173.     // to maintain compatibility with the old LaserWriter SC driver
  174.     {
  175.         BlockMove((Ptr) &((*hPrint)->rPaper), (Ptr) &((*hPrint)->printX[5]), sizeof(Rect));
  176.     }
  177. }
  178. /* EmulatePages */
  179.  
  180.  
  181. /****************************************************************************************
  182.  
  183.                             HandleZoom
  184.                             
  185.     function:
  186.                 This function handles zoom factors from PageSetup.  How does zooming work?  
  187.                 What we do is trick the application into doing the work for us by returning a 
  188.                 page size bigger than actual.  Thus when we render this into the original page
  189.                 size, we get a reduced image.
  190.                 
  191.     parameters:                
  192.                 hPrint            handle to the print record to change
  193.                 
  194.     returns:
  195.                 none
  196.     
  197. ****************************************************************************************/
  198. void HandleZoom(THPrint    hPrint)
  199. {
  200.     gxUniversalPrintRecordPtr    pUniv;
  201.     Fixed                        zoomFactor;
  202.     Rect                        tempRect;
  203.  
  204.     // Convert print record into the universal form
  205.     SD_ConvertPrintRecordTo(hPrint);
  206.     
  207.     pUniv = (gxUniversalPrintRecordPtr) *hPrint;
  208.  
  209.     // Convert the reduction factor into a fixed zoom value 
  210.     zoomFactor = FixRatio(100, pUniv->reduction );
  211.     
  212.     // Notice that we don't zoom the device specific size, since zoom
  213.     //    factors "just" trick out the application side of things 
  214.  
  215.     tempRect = pUniv->appPage;
  216.     SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16),    zoomFactor) ), 
  217.                           FixRound( FixMul( (tempRect.top     << 16),     zoomFactor) ),
  218.                           FixRound( FixMul( (tempRect.right << 16), zoomFactor) ), 
  219.                           FixRound( FixMul( (tempRect.bottom << 16),zoomFactor) ));
  220.     pUniv->appPage = tempRect;
  221.             
  222.     tempRect = pUniv->appPaper;
  223.     SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16),    zoomFactor) ), 
  224.                           FixRound( FixMul( (tempRect.top     << 16), zoomFactor) ),
  225.                           FixRound( FixMul( (tempRect.right << 16), zoomFactor) ), 
  226.                           FixRound( FixMul( (tempRect.bottom << 16),zoomFactor) ));
  227.     pUniv->appPaper = tempRect;
  228.         
  229.     // Convert the print record back into the specific driver form
  230.     SD_ConvertPrintRecordFrom(hPrint);
  231. }
  232. /* HandleZoom */
  233.  
  234.  
  235. /****************************************************************************************
  236.  
  237.                             UpdatePrInfoPt
  238.                             
  239.     function:
  240.                 This function updates the prInfoPT portion of the print record.  The logic
  241.                 for updating the prInfoPT structure comes from the original LaserWriter
  242.                 SC driver.
  243.                 
  244.     parameters:                
  245.                 hPrint        handle to the print record to change
  246.                 
  247.     returns:
  248.                 none
  249.     
  250. ****************************************************************************************/
  251. void UpdatePrInfoPt(THPrint hPrint)
  252. {
  253.     Rect        tempRect;
  254.     TPPrint        pPrint = *hPrint;
  255.     short        precFlags;
  256.     
  257.     // Initially assume the prInfoPT structure will be like that of prInfo
  258.     
  259.     pPrint->prInfoPT.iHRes = pPrint->prInfo.iHRes;
  260.     pPrint->prInfoPT.iVRes = pPrint->prInfo.iVRes;
  261.     pPrint->prInfoPT.rPage = pPrint->prInfo.rPage;
  262.     
  263.     precFlags = pPrint->prXInfo.iBandV;
  264.     
  265.     if ( !TestBit(precFlags, kDevResBit) )    //    T => We're not imaging at device resolution
  266.     {
  267.         short        theRes = pPrint->prInfoPT.iHRes;
  268.         Fixed        scale;
  269.  
  270.         // Compute the new resolution based upon the scaling factors
  271.         
  272.         if ( TestBit(precFlags, kScale75Bit) )
  273.         {
  274.             theRes = (theRes << 2) / 3;
  275.         }
  276.         else 
  277.         if ( TestBit(precFlags, kScale50Bit) )
  278.         {
  279.             theRes <<= 1;
  280.         }
  281.         else 
  282.         if ( TestBit(precFlags, kScale25Bit) )
  283.             theRes <<= 2;
  284.             
  285.         // Update the resolution fields
  286.         
  287.         pPrint->prInfoPT.iHRes = theRes;
  288.         // pPrint->prInfoPT.iVRes = theRes;        // For some reason the old driver doesn't update the iVRes field
  289.  
  290.         // Are we doing exact bitmap scaling, or scaling to the resolution of the device?
  291.         
  292.         if ( TestBit(precFlags, kExactBitBit) )
  293.             scale = FixRatio(kHorizHighExactRes, theRes);
  294.         else
  295.             scale = FixRatio(kHorizHighRes, theRes);
  296.         
  297.         // Now we need to calculate the new rPage
  298.         tempRect =  pPrint->prInfoPT.rPage;
  299.     
  300.         // Calculate the device resolution rectangle
  301.         SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16),    scale) ), 
  302.                               FixRound( FixMul( (tempRect.top     << 16), scale) ),
  303.                               FixRound( FixMul( (tempRect.right << 16), scale) ), 
  304.                               FixRound( FixMul( (tempRect.bottom << 16), scale) ));
  305.     
  306.         // Store away the device page size
  307.         (*hPrint)->prInfoPT.rPage = tempRect;
  308.     }
  309. }
  310. /* UpdatePrInfoPt */
  311.  
  312.  
  313.  
  314. /****************************************************************************************
  315.  
  316.                             UpdatePrintRecord
  317.                             
  318.     function:
  319.                 This function updates the print record based upon the application's
  320.                 calls to PrGeneral.
  321.                 
  322.     parameters:                
  323.                 hPrint            print record to update
  324.                 
  325.     returns:
  326.                 none
  327.     
  328. ****************************************************************************************/
  329. void UpdatePrintRecord(THPrint hPrint)
  330. {
  331.     // emulate those crazy old style pages        
  332.     EmulatePages(hPrint);
  333.  
  334.     // Handle the case of zoom factors by scaling the rectangles
  335.     HandleZoom(hPrint);
  336.  
  337.     // Compute and fill in the devPage rectangle and the remainder of prInfoPT
  338.     UpdatePrInfoPt(hPrint);
  339. }
  340. /* UpdatePrintRecord */
  341.  
  342.  
  343.  
  344. /***************************************************************************************
  345. *                                         INTERFACE ROUTINES                                                     *
  346. ***************************************************************************************/
  347.  
  348. /****************************************************************************************
  349.  
  350.                             SD_PrValidate
  351.                             
  352.     function:
  353.                 This function validates the print record.  If the passed-in print record contains
  354.                 valid information (see below), then it's updated based upon the application's
  355.                 calls to Prgeneral.  Otherwise, it is unchanged, and the return code is true.
  356.                 Otherwise, the print record is defaulted (with SD_PrintDefault), and the 
  357.                 return value is false.
  358.                 
  359.                 Validation:
  360.                     The upper byte of the wDev must be the ID of the device 
  361.                         (kPrinterID in Resources.h).
  362.                     The version of the print record must be current
  363.                         (oldLWSCPrintRecordVersion in Resources.h)
  364.                     (For new print records, we will validate all of the fields which are 
  365.                      public (e.g., paper size), not just these fields)
  366.                 
  367.     parameters:                
  368.                 hPrint                    print record to validate
  369.                 wasChanged                returns true if print record was invalid; false otherwise
  370.                 
  371.     returns:
  372.                 OSErr
  373.     
  374. ****************************************************************************************/
  375. OSErr SD_PrValidate(THPrint hPrint, Boolean *wasChanged)
  376. {
  377.     short        wDev;                        // device specific stuff in this word
  378.     Boolean        returnVal = true;            // initialize return value to "invalid"
  379.                                             //     Why is true == "invalid"? Nobody knows!
  380.     
  381.     // check the wDev.  The upper byte must be equal to kPrinterID.  We get the
  382.     //  wDev, and shift wDev DOWN eight.
  383.         
  384.     wDev =  (*hPrint)->prStl.wDev;
  385.     wDev >>= 8;                                // get just the device ID
  386.  
  387.  
  388.     // If the device id is equal, then check the version number of the print record.
  389.     //    Only if that is also equal to the current version, will we return false (valid).
  390.         
  391.     if (wDev == kPrinterID)
  392.         if ( ((*hPrint)->iPrVersion) == oldLWSCPrintRecordVersion )
  393.             returnVal = false;
  394.             
  395.  
  396.     // If the print record is not valid, then return the default print record.
  397.     // Otherwise, update the print record, based on the application's calls
  398.     // to PrGeneral.
  399.  
  400.     if (returnVal)
  401.         PrintDefault(hPrint);
  402.     else
  403.         UpdatePrintRecord(hPrint);
  404.         
  405.     *wasChanged = returnVal;
  406.     
  407.     return(noErr);
  408. }
  409. /* SD_PrValidate */
  410.  
  411.  
  412. /****************************************************************************************
  413.  
  414.                             SD_ConvertPrintRecordTo
  415.                             
  416.     function:     
  417.                 SD_ConvertPrintRecordTo converts the fields of the print record for
  418.                 the device into the universal print record format.  
  419.                 
  420.     parameters:    
  421.                 hPrint        print record to convert to universal format
  422.     
  423.     returns:
  424.                 OSErr
  425.     
  426. ****************************************************************************************/
  427. OSErr SD_ConvertPrintRecordTo(THPrint hPrint)
  428. {
  429.     gxUniversalPrintRecordPtr    pUniv;
  430.     TPPrint                         pPrint;
  431.     short                        options = 0;
  432.     short                        oldFlags;
  433.  
  434.     pUniv = (gxUniversalPrintRecordPtr) *hPrint;
  435.     pPrint = *hPrint;
  436.     
  437.     // Convert paper feed settings (old and univ setting are switched)
  438.  
  439.     if ( pPrint->prStl.feed == oldPRECAutoFeed )
  440.         pUniv->feed = gxAutoFeed;
  441.     else
  442.         pUniv->feed = gxManualFeed;
  443.     
  444.     // Determine the new options field settings; univ and specific share this location
  445.  
  446.     oldFlags = pPrint->prXInfo.iBandV;
  447.  
  448.     if ( TestBit(oldFlags, kTextSmoothingBit) )
  449.         options |= gxTextSmoothing;
  450.         
  451.     if ( TestBit(oldFlags, kExactBitBit) )
  452.         options |= gxPreciseBitmap;
  453.         
  454.     pUniv->options = options;
  455.  
  456.     // We need to save the settings of the other flag bits from the old print record (e.g. fGrayScale,
  457.     // fDraftBits, etc.).  We save them in printX[18].
  458.     pUniv->printX[18] = oldFlags;
  459.     
  460.     // Now determine the scaling factor, if any, and designate the proper dialog button that
  461.     // corresponds to the scaling factor.  The userCluster1 field specifies the dialog button.
  462.     
  463.     if ( TestBit(oldFlags, kScale75Bit) )
  464.     {
  465.         pUniv->reduction = 75;
  466.         pUniv->userCluster1 = 1;
  467.     }
  468.     else 
  469.     if ( TestBit(oldFlags, kScale50Bit) )
  470.     {
  471.         pUniv->reduction = 50;
  472.         pUniv->userCluster1 = 2;
  473.     }
  474.     else 
  475.     if ( TestBit(oldFlags, kScale25Bit) )
  476.     {
  477.         pUniv->reduction = 25;
  478.         pUniv->userCluster1 = 3;
  479.     }
  480.     else     //    T => No scaling being performed
  481.     {
  482.         pUniv->reduction = 100;
  483.         pUniv->userCluster1 = 0;
  484.     }
  485.  
  486.     // Set the orientation properly
  487.  
  488.     if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )
  489.         pUniv->orientation = gxPortraitOrientation;
  490.     else
  491.         pUniv->orientation = gxLandscapeOrientation;
  492.         
  493.     // Always assign these fields explicit values to ensure they don't cause problems
  494.     
  495.     pUniv->qualityMode         = gxBestQuality;
  496.     pUniv->firstTray         = gxFirstTray;
  497.     pUniv->remainingTray    = gxFirstTray;
  498.     pUniv->coverPage         = gxNoCoverPage;
  499.     pUniv->headMotion         = gxUnidirectionalMotion;
  500.     pUniv->saveFile         = gxNoFile;
  501.     
  502.     return(noErr);
  503. }
  504. /* SD_ConvertPrintRecordTo */
  505.  
  506.  
  507. /****************************************************************************************
  508.  
  509.                             SD_ConvertPrintRecordFrom
  510.                             
  511.     function:     
  512.                 SD_ConvertPrintRecordFrom converts the fields of the print record in 
  513.                 universal print record format into the print record format for the
  514.                 specific device. 
  515.                 
  516.     parameters:    
  517.                 hPrint        print record to convert to device specific format
  518.     
  519.     returns:
  520.                 OSErr
  521.     
  522. ****************************************************************************************/
  523. OSErr SD_ConvertPrintRecordFrom(THPrint hPrint)
  524. {
  525.     gxUniversalPrintRecordPtr    pUniv;
  526.     TPPrint                         pPrint;
  527.     short                        iBandV = 0;
  528.     short                        oldOptions;
  529.     short                        savedOldFlags;
  530.  
  531.     pUniv = (gxUniversalPrintRecordPtr) *hPrint;
  532.     pPrint = *hPrint;
  533.     
  534.     // Set the orientation properly
  535.  
  536.     if (pUniv->orientation == gxPortraitOrientation)
  537.         pPrint->prStl.wDev |= kPortraitBit;
  538.     else
  539.         pPrint->prStl.wDev &= ~kPortraitBit;
  540.  
  541.     // Convert paper feed settings (old and univ setting are switched)
  542.  
  543.     if ( pUniv->feed == gxAutoFeed )
  544.         pPrint->prStl.feed = oldPRECAutoFeed;
  545.     else
  546.         pPrint->prStl.feed = oldPRECManualFeed;
  547.  
  548.     // Set the flags in the iBandV field of the print record
  549.  
  550.     oldOptions = pUniv->options;
  551.     
  552.     if ( TestBit(oldOptions, gxTextSmoothing) )
  553.         iBandV |= kTextSmoothingBit;
  554.         
  555.     switch( pUniv->userCluster1 )    //    Based on the scaling dialog button setting, set the scaling factor
  556.     {
  557.         case 0:
  558.             break;
  559.             
  560.         case 1:
  561.             iBandV |= kScale75Bit;
  562.             break;
  563.             
  564.         case 2:
  565.             iBandV |= kScale50Bit;
  566.             break;
  567.             
  568.         case 3:
  569.             iBandV |= kScale25Bit;
  570.             break;
  571.     }
  572.     
  573.     if ( TestBit(oldOptions, gxPreciseBitmap) )
  574.         iBandV |= kExactBitBit;
  575.  
  576.     savedOldFlags = pUniv->printX[18];
  577.     
  578.     if ( TestBit(savedOldFlags, kDevResBit) )
  579.         iBandV |= kDevResBit;
  580.  
  581.     if ( TestBit(savedOldFlags, kDraftBitsBit) )
  582.         iBandV |= kDraftBitsBit;
  583.  
  584.     if ( TestBit(savedOldFlags, kAbortChkBit) )
  585.         iBandV |= kAbortChkBit;
  586.  
  587.     if ( TestBit(savedOldFlags, kGrayScaleBit) )
  588.         iBandV |= kGrayScaleBit;
  589.  
  590.     // Initialize the remaining fields in the TPrXInfo structure
  591.     
  592.     pPrint->prXInfo.iBandV = iBandV;
  593.     pPrint->prXInfo.iBandH = 0;
  594.     pPrint->prXInfo.iDevBytes = 0;
  595.     pPrint->prXInfo.iBands = 0;
  596.     pPrint->prXInfo.bPatScale = kPatScale;
  597.     pPrint->prXInfo.bUlThick = 0;
  598.     pPrint->prXInfo.bUlOffset = 0;
  599.     pPrint->prXInfo.bUlShadow = 0;
  600.     pPrint->prXInfo.scan = scanTB;
  601.     pPrint->prXInfo.bXInfoX = 0;
  602.  
  603.     pPrint->printX[18] = 0;
  604.  
  605.     return(noErr);
  606. }
  607. /* SD_ConvertPrintRecordFrom */
  608.